/*
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *    2011 year
 *    Author: Michael Khromov aka MikeDM (Mike D'Morto)
 *    E-Mail: mikedmorto@gmail.com
 */


/*
Интерфейс для плагинов баз данных
*/

#ifndef IDATABASE_H
#define IDATABASE_H

#include <QtCore/QtPlugin>
#include <QStringList>
#include "mdata.h"


class iDatabase : public QObject{
public:
    virtual ~iDatabase(){};
    virtual bool init(const QStringList & cfg, const QString & lng)=0;
    virtual QString getlastError()=0;
public slots:
    // асинхронный запрос
    virtual void slotQuery(const QString & pl_name, const QString & metaf_name, QStringList & params)=0;
    // удаление результата из очереди результатов
    virtual void slotFreeRes(int id)=0;
    // слот завершения работы с базой
    virtual void slotStop()=0;
    // начало синхронной сессии
    virtual void slotStartSync(const QString & pl_name)=0;
    // синхронный запрос
    virtual void slotQueryCync(const QString & pl_name, const QString & metaf_name, QStringList & params)=0;
    // конец синхронной сессии
    virtual void slotStopSync(const QString & pl_name)=0;

signals:
    // посылаем данные в протокол
    virtual void sigPutLog(const QString & owner, int level, const QString & text)=0;
    // посылаем положительный результат на асинхронный запрос
    virtual void sigFinish( const QString & pl_name, int id, Mdata * data)=0;
    // возникла ошибка в работе запросов.
    virtual void sigError(const QString & pl_name, const QString & errtext)=0;
    // положительный ответ на начало синхронной сессии
    virtual void sigStartSync(const QString & pl_name)=0;

};

Q_DECLARE_INTERFACE(iDatabase,"ru.usldb.idatabase")
#endif //IDATABASE_H


/*
схема работы плагинов баз данных а конкретно на примере libdb_mysql

плагин баз данных работает одновременно минимум в двух потоках
1 поток связан с ядром и обеспечивает сигнально слотовую связь
а во втором потоке проходит действительная работа с базой, там и существует
единственное соединение с базой. хотя при желании можно будет сделать множественное соединие
что действительно позволит реальную асинхронность дейстивий НО может повлечь разногласия
в работе базы или еще хуже увеличить нагрузку. сие падает на плечи разработчика
плагина базы данных

после загрузки ядром плагина бд, выполняется инициализация и последующее связывание сигналов и слотов
с этого места поподробнее:
каждый плагин бд имеет ряд слотов:
1 - слот асинхронного запроса с параметрами:
    - имя плагина совершившего запрос
    - название метафункции
    - список параметров

2 - слот начала синхронной работы с одним параметром - имя плагина инициировавшего такую работу
3 - слот синхронного запроса, параметры те же что и у асинхронного
4 - слот окончания синхронной работы. с одним параметром - имя плагина запрашивающего конец работы режима
    Важно то, что закончить синхронный режим может только тот кто начал.

5 - слот окончания работы плагина. необходим для корректного завершения работы с бд.
6 - слот удаления возвращенных данных из очереди. передается ид

каждый плагин бд имеет список сигналов:
1 - сигнал об окончании запроса:
    - какому плагину пренадлежит ответ
    - номер ответа в глобальной очереди
    - указатель на экземпляр ответа ( унивесальный абстрактный класс реализуется в каждом плагине бд )

2 - сигнал об ошибке
    - какому плагину пренадлежит ответ
    - текст ошибки

3 - сигнал записи в лог:
    - имя плагина
    - уровень важности события
    - текст записи

4 - сигнал о начале работы в синхронном режиме:
    - какому плагину преднозначен


штатная работа в асинхронном режиме:
1 - плагину бд приходит сигнал на слот запроса.
2 - плагин бд ложит поступивший запрос в очередь для второго потока и ожидает следующих сигналов от ядра.
3 - как только второй поток возвращает результат, ошибочный или нормальный то он уходит сигналом к ядру.

фокус такого режима в том, что несколько рабочих плагинов могут одновременно делать запросы к плагину бд и
ожидать ответа, а при желании второй поток бд может в несколько очередей обратывать поступающие запросы, но
если необходимо выполнить последовательность запросов изменяющих данные может возникнуть разногласие и для
этого существет следующий режим:

штатная работа в асинхронном режиме:
данный режим блокирует обработку запросов от других плагинов, и они копятся в соответствующих очередях.
выполняются запросы только от одного плагина который инициировал синхронный режим до закрытия режима.
Это позволяет исключить разногласия и работать с базой поддерживающей транзакции либо создавать блокировки.

1 - плагину бд приходит сигнал на слот начала работы в синхронном режиме, с этого момента все остальные запросы асинхронные или
    новые запросы начала синхронного режима от других плагинов ставятся в очередь. Разработчикам рабочих плагинов нужно
    помнить о необходимости начала и конца синхронного режима, ибо если не закрывать этот режим, то другие плагины не смогут
    обращаться к базе. это по всей видимости будет основной проблемой для разработчикав плагинов -))))

2 - плагину бд приходит сигнал на слот запроса в синхронном режиме: тут точно так же как и в асинхронном, запрос проталкивается во
    второй поток, и плагин бд ждет решения от него

3 - от второго потока возвращается результат, который и перенаправляется дальше ядру и рабочим плагинам сигналом
    либо ошибочный либо нормальный

4 - тут происходит либо ожидание следующего сигнала на запрос данных в синхронном режиме либо сигнал окончания работы
    в синхронном режиме.
*/
